using System;
using System.Collections.Generic;
using Extensions.FPMath;
using Game.Core;
using UnityEngine;

namespace Game.Config
{
    [Serializable]
    public struct PropertyConfigData
    {
        public int ID;

        public float Strength; // 力量
        public float Dexterity; // 敏捷
        public float Constitution; // 体质
        public float Intellectual; // 智力
        public float Lucky; // 幸运
        public float Charisma; // 魅力

        public float MaxEncumbered;
        public float MaxHealthPoint;
        public float HealthRecover;
        public float AbilityPower;
        public float MaxAbilityPoint;
        public float AbilityRecover;
        public float AttackRange;
        public float AttackSpeed;
        public float MinMeleeAttack;
        public float MaxMeleeAttack;
        public float MinRangeAttack;
        public float MaxRangeAttack;
        public float Armor;
        public float Resistance;
        public float Penetration;
        public float Block;
        public float Dodge;
        public float Hit;
        public float CritRate;
        public float CritRatio;
        public float ExtraDamage;
        public float MaxTroops;

        public float MoveSpeed;
        
        public PropertyInfo ToPropertyInfo()
        {
            return new PropertyInfo()
            {
                Strength = Strength,
                Dexterity = Dexterity,
                Constitution = Constitution,
                Intellectual = Intellectual,
                Lucky = Lucky,
                Charisma = Charisma,
                
                MaxEncumbered = MaxEncumbered,
                MaxHealthPoint = MaxHealthPoint,
                HealthRecover = HealthRecover,
                AbilityPower = AbilityPower,
                MaxAbilityPoint = MaxAbilityPoint,
                AbilityRecover = AbilityRecover,
                AttackRange = AttackRange,
                AttackSpeed = AttackSpeed,
                MinMeleeAttack = MinMeleeAttack,
                MaxMeleeAttack = MaxMeleeAttack,
                MinRangeAttack = MinRangeAttack,
                MaxRangeAttack = MaxRangeAttack,
                Armor = Armor,
                Resistance = Resistance,
                Penetration = Penetration,
                Block = Block,
                Dodge = Dodge,
                Hit = Hit,
                CritRate = CritRate,
                CritRatio = CritRatio,
                ExtraDamage = ExtraDamage,
                MaxTroops = MaxTroops,
                
                MoveSpeed = MoveSpeed,
            };
        }
    }

    [CreateAssetMenu(menuName = "GameConfigs/PropertyConfig")]
    public class PropertyConfig : ScriptableObject
    {
        public float ConstitutionToHealthPoint = 25.0f;
        public float ConstitutionToHealthRecover = 0.05f;
        
        public List<PropertyConfigData> PropertyDatas = new List<PropertyConfigData>();
        private static Dictionary<int, PropertyConfigData> m_DictPropertyData;

        public static bool InitPropertyData()
        {
            if (null != m_DictPropertyData && m_DictPropertyData.Count > 0) return true;

            var config = Resources.Load("Configs/PropetyConfig") as PropertyConfig;
            if (null == config) return false;
            
            m_DictPropertyData = new Dictionary<int, PropertyConfigData>();
            for (int i = 0; i < config.PropertyDatas.Count; i++)
            {
                m_DictPropertyData.Add(i, config.PropertyDatas[i]);
            }
            return true;
        }

        public static void ReleasePropertyData() => m_DictPropertyData.Clear();

        public static PropertyConfigData GetPropertyData(int id)
        {
           if (!InitPropertyData()) return default;
           if (m_DictPropertyData.TryGetValue(id, out var result))
               return result;
           return default;
        }
    }
}